﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using EHR.Ctrls.QueryDesign;
using System.Xml.Linq;
using System.Windows.Data;
using EHR.Views;
using System.Reflection;
using System.IO;
using System.Text;
using CommunitySystem;
using CommunitySystem.Views;
using CommunitySystem.DataQueryService;

namespace EHR.Ctrls.QueryDesign
{
    public partial class DataQueryView : AsyncCtrl
    {
        private ViewDesignInfo _viewDesignInfo;
        private IDictionary<string, ColInfo> _dicCols;
        private XElement _data;
        private PagedCollectionView _pageVeiw;
        private IList<FilterInfo> _filters = new List<FilterInfo>();
        private Stream _stream;

        public DataQueryView()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
        }

        public void Query(ViewInfo viewInfo)
        {
            if (viewInfo == null)
            {
                dataGrid.Columns.Clear();
                dataGrid.ItemsSource = null;
                filterPanel.Visibility = Visibility.Collapsed;
                return;
            }
            filterPanel.Visibility = Visibility.Visible;

            XElement el = XElement.Parse(viewInfo.XML);
            _viewDesignInfo = new ViewDesignInfo();
            _viewDesignInfo.FromXml(el);
            _dicCols = MakeDic(_viewDesignInfo.Columns);
            //
            BuildDataGrid(_viewDesignInfo);

            Worker.IsBusy = true;
            DataQueryClient client = new DataQueryClient();
            client.GetViewRecordsCompleted += client_GetViewRecordsCompleted;
            client.GetViewRecordsAsync(viewInfo.XML);
        }

        private IDictionary<string, ColInfo> MakeDic(IList<ColInfo> cols)
        {
            IDictionary<string, ColInfo> dic = new Dictionary<string, ColInfo>();
            foreach (ColInfo col in cols)
            {
                dic.Add(col.FieldName, col);
            }
            return dic;
        }

        void client_GetViewRecordsCompleted(object sender, GetViewRecordsCompletedEventArgs e)
        {
            Worker.IsBusy = false;
            _data = XElement.Parse(e.Result);
            DataLoaded = true;
        }

        protected override void PageDataLoaded()
        {
            IList<object> list = DataModelBuilder.BuildObjectList(_viewDesignInfo, _data);
            _pageVeiw = new PagedCollectionView(list);
            _pageVeiw.Filter = FilterObjects;
            dataGrid.ItemsSource = _pageVeiw;
        }

        private void BuildDataGrid(ViewDesignInfo viewDesign)
        {
            dataGrid.Columns.Clear();

            IList<ColInfo> colInfoList = new List<ColInfo>();
            foreach (ColInfo ci in viewDesign.Columns)
            {
                if (ci.IsVisible)
                {
                    colInfoList.Add(ci);
                    //
                    if (ci.FieldType == FieldType.Bool)
                    {
                        DataGridCheckBoxColumn col = new DataGridCheckBoxColumn();
                        col.Width = new DataGridLength(ci.Width);
                        col.Header = ci.DisplayName;
                        col.Binding = new Binding(ci.FieldName) { StringFormat = ci.StringFormat };

                        dataGrid.Columns.Add(col);
                    }
                    else
                    {
                        if (ci.DisplayName == "姓名")
                        {
                            DataGridTemplateColumn col = new DataGridTemplateColumn();
                            col.CellTemplate = NameColTemplate;//在XAML文件中
                            col.Width = new DataGridLength(ci.Width);//更改成ci.Width
                            col.Header = ci.DisplayName;//更改成ci.DisplayName;
                            dataGrid.Columns.Add(col);
                        }
                        else
                        {
                            DataGridTextColumn col = new DataGridTextColumn();
                            col.Width = new DataGridLength(ci.Width);
                            col.Header = ci.DisplayName;
                            col.Binding = new Binding(ci.FieldName) { StringFormat = ci.StringFormat };

                            dataGrid.Columns.Add(col);
                        }
                    }
                }
            }

            //
            _filters = new List<FilterInfo>();
            filterPanel.Clear();
            filterPanel.Columns = colInfoList;
        }

        private void filterPanel_ConditionPrepared(object sender, EventArgs e)
        {
            if (_pageVeiw == null)
            {
                return;
            }

            _filters = filterPanel.GetFilters();

            _pageVeiw.Refresh();
        }

        public bool FilterObjects(object obj)
        {
            IList<FilterInfo> filters = _filters;
            if (filters.Count == 0)
            {
                return true;
            }

            bool b = true;
            for (int i = 0; i < filters.Count; i++)
            {
                FilterInfo fi = filters[i];
                if (i == 0)
                {
                    b = FilterResult(fi, obj);
                }
                else
                {
                    if (fi.IsAnd)
                    {
                        b = b && FilterResult(fi, obj);
                    }
                    else
                    {
                        b = b || FilterResult(fi, obj);
                    }
                }
            }

            return b;
        }

        private bool FilterResult(FilterInfo fi, object obj)
        {
            ColInfo col = _dicCols[fi.FieldName];
            object pVal = obj.GetProperty(fi.FieldName);
            object fiVal = GetFilterValue(col, fi);
            switch (fi.Op)
            {
                case FilterOp.等于:
                    return IsEqual(col, pVal, fiVal);
                case FilterOp.不等于:
                    return !IsEqual(col, pVal, fiVal);
                case FilterOp.大于:
                    return Greater(col, pVal, fiVal);
                case FilterOp.大于等于:
                    return Greater(col, pVal, fiVal) || IsEqual(col, pVal, fiVal);
                case FilterOp.小于:
                    return Less(col, pVal, fiVal);
                case FilterOp.小于等于:
                    return Less(col, pVal, fiVal) || IsEqual(col, pVal, fiVal);
                case FilterOp.始于:
                    return (pVal as string).StartsWith((fiVal as string));
                case FilterOp.包含:
                    return (pVal as string).IndexOf((fiVal as string)) != -1;
                default:
                    throw new Exception("没有此FilterOp枚举值");
            }
            return true;
        }

        private object GetFilterValue(ColInfo col, FilterInfo fi)
        {
            if (string.IsNullOrEmpty(fi.Value))
            {
                if (col.FieldType == FieldType.String)
                {
                    return "";
                }
                else
                {
                    return null;
                }
            }

            switch (col.FieldType)
            {
                case FieldType.String:
                    return fi.Value;
                case FieldType.Bool:
                    return fi.Value != "0";
                case FieldType.Int:
                    return int.Parse(fi.Value);
                case FieldType.Float:
                    return double.Parse(fi.Value);
                case FieldType.DateTime:
                    return DateTime.Parse(fi.Value);
                default:
                    throw new Exception("没有此FieldType枚举值！");
            }
        }

        private bool IsEqual(ColInfo col, object pVal, object fiVal)
        {
            if (col.FieldType == FieldType.String)
            {
                if (string.IsNullOrEmpty(pVal as string) && string.IsNullOrEmpty(fiVal as string))
                {
                    return true;
                }
            }
            else
            {
                if (pVal == null || fiVal == null)
                {
                    return pVal == null && fiVal == null;
                }
            }

            switch (col.FieldType)
            {
                case FieldType.String:
                    return string.Compare((string)pVal, (string)fiVal) == 0;
                case FieldType.Bool:
                    return (bool)pVal == (bool)fiVal;
                case FieldType.Int:
                    return (int)pVal == (int)fiVal;
                case FieldType.Float:
                    return (double)pVal == (double)fiVal;
                case FieldType.DateTime:
                    return DateTime.Compare((DateTime)pVal, ((DateTime)fiVal)) == 0;
                default:
                    throw new Exception("没有此FieldType枚举值！");
            }
        }

        private bool Greater(ColInfo col, object pVal, object fiVal)
        {
            if (pVal == null)
            {
                return false;
            }

            switch (col.FieldType)
            {
                case FieldType.String:
                    return string.Compare((string)pVal, (string)fiVal) > 0;
                case FieldType.Bool:
                    throw new Exception("bool类型不允许有<操作！");
                case FieldType.Int:
                    return (int)pVal > (int)fiVal;
                case FieldType.Float:
                    return (double)pVal > (double)fiVal;
                case FieldType.DateTime:
                    return DateTime.Compare((DateTime)pVal, ((DateTime)fiVal)) > 0;
                default:
                    throw new Exception("没有此FieldType枚举值！");
            }
        }

        private bool Less(ColInfo col, object pVal, object fiVal)
        {
            if (pVal == null)
            {
                return false;
            }

            switch (col.FieldType)
            {
                case FieldType.String:
                    return string.Compare((string)pVal, (string)fiVal) < 0;
                case FieldType.Bool:
                    throw new Exception("bool类型不允许有<操作！");
                case FieldType.Int:
                    return (int)pVal < (int)fiVal;
                case FieldType.Float:
                    return (double)pVal < (double)fiVal;
                case FieldType.DateTime:
                    return DateTime.Compare((DateTime)pVal, ((DateTime)fiVal)) < 0;
                default:
                    throw new Exception("没有此FieldType枚举值！");
            }
        }

        private void btnExportExcel_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog()
            {
                Filter = "Excel文件 (*.xls)|*.xls"
            };

            if (!(bool)dlg.ShowDialog())
            {
                return;
            }
            try
            {
                _stream = dlg.OpenFile();
            }
            catch
            {
                MessageBox.Show("其它程序正在使用该文件，请关闭使用该文件的程序后重试！");
                return;
            }

            Worker.IsBusy = true;
            DataQueryClient client = new DataQueryClient();
            client.TableExportExcelCompleted += client_TableExportExcelCompleted;
            client.TableExportExcelAsync(DataToXml());
        }

        void client_TableExportExcelCompleted(object sender, TableExportExcelCompletedEventArgs e)
        {
            try
            {
                byte[] buffer = e.Result;
                _stream.Write(buffer, 0, buffer.Length);
            }
            finally
            {
                Worker.IsBusy = false;
                _stream.Close();
                _stream = null;
            }
        }

        private string DataToXml()
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 9000; i++)
            {
                sb.Append("1");
            }
            return sb.ToString();
            XElement xTable = new XElement("Table",
                new XAttribute("Name", _viewDesignInfo.ViewName));
            XElement xCols = new XElement("Columns");
            xTable.Add(xCols);
            IList<ColInfo> cols = (from ci in _viewDesignInfo.Columns where ci.IsVisible select ci).ToList();
            foreach (var col in cols)
            {
                XElement xCol = new XElement("Column",
                    new XAttribute("Name", col.FieldName),
                    new XAttribute("DisplayName", col.DisplayName),
                    new XAttribute("Width", col.Width));
                xCols.Add(xCol);
            }

            XElement xRows = new XElement("Rows");
            xTable.Add(xRows);

            Type type = null;
            foreach (var i in _pageVeiw)
            {
                XElement xRow = new XElement("Row");
                xRows.Add(xRow);

                if (type == null)
                {
                    type = i.GetType();
                }

                foreach (var col in cols)
                {
                    object field = type.GetProperty(col.FieldName).GetValue(i, null);
                    string strfmt = string.IsNullOrEmpty(col.StringFormat) ? "{0}" : "{0:" + col.StringFormat + "}";
                    string str = field == null ? "" : string.Format(strfmt, field);
                    xRow.Add(new XAttribute(col.FieldName, str));
                }
            }

            string xml = xTable.ToString();
            return xml;
        }

        private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // MessageBox.Show("aa");
            BeginShowEmpInfo((sender as TextBlock).Tag.ToString());
        }

        private void ShowEmpInfo(int empId)
        {
            //EmployeeView empView = new EmployeeView() { Id = empId };
            //empView.PageLoaded = true;
            //empView.Id = empId;
            //ChildBox.Show("", empView);
        }

        private void BeginShowEmpInfo(string EmpNO)
        {
            Worker.IsBusy = true;
            DataQueryClient client = new DataQueryClient();
            client.GetEmpIdByEmpNOCompleted += client_GetEmpIdByEmpNOCompleted;
            client.GetEmpIdByEmpNOAsync(EmpNO);
        }

        void client_GetEmpIdByEmpNOCompleted(object sender, GetEmpIdByEmpNOCompletedEventArgs e)
        {
            Worker.IsBusy = false;
            ShowEmpInfo(e.Result);//上一封邮件发给你的方法 
        }


    }
}
